home *** CD-ROM | disk | FTP | other *** search
- /**************************************************************************
- PCX2FNT - by Lee Hamel (Patch), hamell@cx.pdx.edu, *Avalanche* coder
- July 14th, 1993
- **************************************************************************/
-
- #include <stdio.h>
- #include <string.h>
- #include <malloc.h>
-
- #undef DEBUG1
- #undef DEBUG2
- #undef DEBUG3
- #undef DEBUG4
- #undef DEBUG5
- #undef DEBUG6
- #undef DEBUG7
- #undef DEBUG8
- #undef DEBUG9
-
- typedef struct {
- char manufacturer;
- char version;
- char encoding;
- char bits_per_pixel;
- int xmin,ymin;
- int xmax,ymax;
- int hres;
- int vres;
- char palette[48];
- char reserved;
- char colour_planes;
- int bytes_per_line;
- int palette_type;
- char filler[58];
- } PCXHEAD;
-
- #define PCXHEADSIZE sizeof(PCXHEAD)
-
- PCXHEAD header;
- unsigned int width, depth, bytes, i, i1, i2, i3, charcount = 0;
- unsigned char palette[768];
- unsigned char charrows, charsinrow[20], numcolors = 0, startcolor = 0;
- unsigned char buffer[256], charorder[256], xysizes[512], showflag;
- FILE *infile, *outfile;
- unsigned char *tempptr, *charptr, *rowptr, *picture, *fonts[256];
- char pcxfile[20],cfgfile[20],fntfile[20],asmfile[20];
-
- void Read_PCX_Line(unsigned int vidoffset)
- {
- unsigned char c, run;
- unsigned int n = 0;
-
- _asm
- {
- cld
- mov di,[vidoffset]
- }
-
- do
- {
- c = fgetc(infile) & 0xff;
- if ((c & 0xc0) == 0xc0) /* if it's a run of bytes field */
- {
- run = c & 0x3f; /* and off the high bits */
- c = fgetc(infile); /* get the run byte */
- n += run; /* run the byte */
- buffer[c] = 1;
- for (i2 = 0; i2 < run; i2++)
- *picture++ = c;
-
- if (showflag == 0)
- {
- _asm
- {
- mov ax,0a000h
- mov es,ax
- mov al,[c]
- xor ch,ch
- mov cl,[run]
- rep stosb
- }
- }
- }
- else
- {
- n++;
- buffer[c] = 1;
- *picture++ = c;
-
- if (showflag == 0)
- {
- _asm
- {
- mov ax,0a000h
- mov es,ax
- mov al,[c]
- stosb
- }
- }
- }
- }
- while (n < bytes);
- }
-
- void Unpack_PCX_File(void)
- {
- for (i = 0; i < 768; i++)
- palette[i] = palette[i] >> 2;
-
- if (showflag == 0)
- {
- _asm
- {
- mov ax,0013h
- int 10h
- mov ax,1012h
- xor bx,bx
- mov cx,256
- mov dx,offset palette
- int 10h
- }
- }
-
- rowptr = picture = (unsigned char *) malloc((size_t) 64000);
- for (i = 0; i < depth; i++)
- Read_PCX_Line(i * 320);
- }
-
- void Get_CFG_File(char *cfgfile)
- {
- char tempstr[80],temp1[5],temp2[5],num[5];
- FILE *fp;
-
- for (i = 0; i < 512; i++)
- xysizes[i] = 0;
-
- i = 0;
- if ((fp = fopen(cfgfile,"rt")) != NULL)
- {
- do
- {
- fgets(tempstr,80,fp);
- }
- while (tempstr[0] == ';' || tempstr[0] == '\n');
-
- #ifdef DEBUG8
- printf("Tempstr[0] and [1] = [%d] [%d]\n",tempstr[0],tempstr[1]);
- #endif
-
- sscanf(tempstr,"%s = %d",tempptr,& charrows);
- fgets(tempstr,80,fp);
- tempptr = strchr(tempstr,'=');
- tempptr += 2;
-
- #ifdef DEBUG8
- printf("Charrows = [%d]\n",charrows);
- #endif
-
- for (i = 0; i < charrows; i++)
- {
- sscanf(tempptr,"%d",& charsinrow[i]);
-
- #ifdef DEBUG8
- printf("Charsinrow[%d] = [%d]\n",i,charsinrow[i]);
- #endif
-
- while (*tempptr != ' ') tempptr++;
- tempptr++;
- }
-
- i = 0;
- while (fgets(tempstr,80,fp) != NULL)
- {
- if (tempstr[0] != ';' && tempstr[0] != '\n')
- {
- if (sscanf(tempstr,"%s = %s x %s",num,temp1,temp2) != -1)
- {
- #ifdef DEBUG1
- printf("Num = [%s], Temp1 = [%s], Temp2 = [%s]\n",
- num,temp1,temp2);
- #endif
-
- charorder[i++] = atoi(num);
- charcount++;
- xysizes[2*atoi(num) + 0] = atoi(temp1);
- xysizes[2*atoi(num) + 1] = atoi(temp2);
- }
- }
- }
- fclose(fp);
- }
- else
- {
- fcloseall();
- printf("Could not open file %s\n",cfgfile);
- exit(1);
- }
-
- #ifdef DEBUG1
- for (i = 0; i < 256; i++)
- printf("Index[%3d] = x(%d), y(%d)\n",i,xysizes[i*2],xysizes[(i*2)+1]);
- #endif
- }
-
- void Dump_Fonts(void)
- {
- unsigned int ord = 0, xsize, ysize, highesty;
-
- #ifdef DEBUG4
- for (i = 0; i < 256; i++)
- {
- fonts[i] = (char *) malloc((size_t) 2);
- *fonts[i] = i;
- *(fonts[i] + 1) = i + 1;
- }
- for (i = 0; i < 256; i++)
- printf("Fonts[%d] = %d %d\n",i,*fonts[i],*(fonts[i]+1));
- free((char *) fonts);
- return;
- #endif
-
- #ifdef DEBUG5
- for (ord = 0; ord < charcount; ord++)
- printf("char [%c] [%3d] x-size = %2d\ty-size = %2d\n",
- charorder[ord], charorder[ord],
- xysizes[charorder[ord]*2],
- xysizes[(charorder[ord]*2)+1]);
- return;
- #endif
-
- #ifdef DEBUG6
- picture = rowptr + 320;
- for (i = 0; i < xysizes[charorder[ord]*2]; i++)
- printf("Bitmap = %3d\n",*picture++);
- return;
- #endif
-
- for (i = 0; i < charrows; i++)
- {
- /* reset pointer to UL corner of character row */
- /* +320 to skip over blank row */
-
- highesty = 0; /* longest font initialize */
- rowptr += 320;
- picture = rowptr;
-
- for (i3 = 0; i3 < charsinrow[i]; i3++)
- {
- /* UL corner of char */
- charptr = picture;
- xsize = xysizes[charorder[ord]*2];
- ysize = xysizes[(charorder[ord]*2)+1];
-
- #ifdef DEBUG9
- printf("Ord = [%d] Charorder[ord] = [%d]\n",
- ord,charorder[ord]);
- printf("Xsize = [%d] Ysize = [%d]\n",xsize,ysize);
- #endif
-
- if (ysize > highesty) highesty = ysize;
-
- tempptr = fonts[charorder[ord]] =
- (unsigned char *) malloc((size_t) xsize * ysize);
-
- for (i1 = 0; i1 < xsize; i1++) /* X value */
- {
- for (i2 = 0; i2 < ysize; i2++) /* Y value */
- {
- *tempptr++ = *picture;
- picture += 320;
- }
-
- picture++; /* next column over */
- picture -= 320*ysize; /* back to top of column */
- }
-
- ord++; /* next char in order */
- picture = charptr + xsize + 1; /* jump to next UL corner */
- }
- /* Jump to start of next char row */
- rowptr += (320 * highesty);
-
- #ifdef DEBUG7
- printf("Ord = [%u] Highesty = [%u]\n",
- ord, highesty);
- #endif
- }
-
- i1 = 1285;
- for (i = 0; i < 256; i++)
- {
- xsize = xysizes[i*2];
- ysize = xysizes[(i*2)+1];
- fwrite(&i1, 2, 1, outfile);
- i1 += (xysizes[i * 2] * xysizes[(i * 2) + 1]) + 3;
- }
-
- for (i = 0; i < 256; i++)
- {
- xsize = xysizes[i*2];
- ysize = xysizes[(i*2)+1];
- if (xsize == 0 && ysize == 0)
- fprintf(outfile,"%c%c%c",i,0,0);
- else
- {
- fprintf(outfile,"%c%c%c",i,xsize,ysize);
- for (i1 = 0, charptr = fonts[i]; i1 < xsize * ysize; i1++)
- fprintf(outfile,"%c",*charptr++);
- }
- }
-
- for (i = 0; i < charcount; i++)
- free((unsigned char *) fonts[i]);
- }
-
- void Help(char helptype)
- {
- printf("\n");
- printf("PCX2FNT - Converts a PCX pic to FNT format\n");
- printf(" by Patch (hamell@rigel.cs.pdx.edu) \n");
- printf("──────────────────────────────────────────\n");
- if (helptype == 1)
- {
- printf("FNT format\n");
- printf("──────────\n");
- printf("byte 00h - 02h : string signature 'LMH' (for error checking)\n");
- printf("byte 03h : # of colors used by the fonts\n");
- printf("byte 04h : starting palette color used by the fonts\n");
- printf("byte 05h - 772 : RGB data for 256 possible colors\n");
- printf("word 773 - 1284: offset of all 256 ASCII chars, relative to byte 0\n");
- printf("byte 1285 - : data for the fonts\n");
- printf(" 1st byte is the char in the ASCII table\n");
- printf(" 2nd byte is the X size (width)\n");
- printf(" 3rd byte is the Y size (height)\n");
- printf(" X*Y bytes of the font - saved column by column\n");
- printf(" top to bottom, left to right\n\n");
- printf("Fonts are expected to be in the following format:\n");
- printf("┌─┬─┬─┬─┬─┬──┬──── Note the 0s along the top row and far right column.\n");
- printf("0 0 0 0 0 0 ─┤ This is an example of the pixel placement of an A.\n");
- printf("0 1 1 1 0 0 ─┤ The 1s represent where the different colors are at.\n");
- printf("1 1 1 1 1 0 ─┤ When drawing the fonts, make sure each lettter has a\n");
- printf("1 1 0 1 1 0 ─┤ border along the top side, otherwise the conversion\n");
- printf("1 1 1 1 1 0 ─┤ algorithm will mess up. Just stack all of your fonts\n");
- printf("1 1 0 1 1 0 ─┤ on top of each other and side by side, save the picture\n");
- printf("1 1 0 1 1 0 ─┤ as a PCX, and you're done!\n");
- }
- else
- {
- printf("Usage: pcx2fnt [-FNT] PCXFILE [-SHOW]\n");
- printf("where: -FNT - show the FNT format\n");
- printf(" PCXFILE - the PCX file to read (no extension)\n");
- printf(" -SHOW - show the PCX on the screen\n\n");
- printf("Example call: pcx2fnt fontfile -show\n");
- printf("- This will read the file FONTFILE, show it to the screen, and\n");
- printf(" will read the configuration information from FONTFILE.CFG.\n\n");
- printf("Example FONTFILE.CFG:\n");
- printf("charrows = 4\n");
- printf("charsinrow = 3 4 5 6\n");
- printf("065 = 10 x 10\n\n");
- printf("The program expects 4 rows of fonts with 3 fonts in the 1st row, 4 in the 2nd,\n");
- printf("5 in the 3rd, and 6 in the 4th. 065 represents ASCII char A, and it is a\n");
- printf("10 x 10 bitmap. The file FONTFILE.FNT will be created. Use a paint\n\n");
- printf("program to figure out the pixel count. The blank border along the top and right\n");
- printf("of each font DOES NOT count as part of the height or width!\n");
- }
- exit(1);
- }
-
- void main(int argc, char *argv[])
- {
- if (stricmp("-FNT",argv[1]) == 0) Help(1);
- if (argc == 1) Help(0);
-
- {
- strcpy(pcxfile,argv[1]);
- strcpy(cfgfile,argv[1]);
- strcpy(fntfile,argv[1]);
- strcpy(asmfile,argv[1]);
- strcat(pcxfile,".pcx");
- strcat(cfgfile,".cfg");
- strcat(fntfile,".fnt");
- strcat(asmfile,".asm");
-
- if ((infile = fopen(pcxfile,"rb")) != NULL)
- {
- if (fread((char *)&header,1,PCXHEADSIZE,infile) == PCXHEADSIZE)
- {
- if (header.manufacturer == 0x0a && header.version == 5)
- {
- if (!fseek(infile,-769L,SEEK_END))
- {
- if (fgetc(infile) == 0x0c && fread(palette,1,768,infile) == 768)
- {
- fseek(infile,128L,SEEK_SET);
- width = header.xmax - header.xmin + 1;
- depth = header.ymax - header.ymin + 1;
- bytes = header.bytes_per_line;
-
- /*
- printf("Width = %d\n",width);
- printf("Depth = %d\n",depth);
- printf("Bytes = %d\n",bytes);
- printf("Chars per row = %d\n",charsrow);
- */
-
- showflag = stricmp("-SHOW",argv[2]);
- Get_CFG_File(cfgfile);
- Unpack_PCX_File();
-
- #ifdef DEBUG2
- for (i = 0; i < 256; i++)
- printf("Charorder[%3d] = %d\n",i,charorder[i]);
- #endif
-
- #ifdef DEBUG3
- for (i = 0; i < 256; i++)
- printf("Buffer[%3d] = %d\n",i,buffer[i]);
- #endif
-
- outfile = fopen(fntfile,"wb");
-
- for (i = 1; i < 255; i++) /* ignore use of colors 0 and 255 */
- if (buffer[i] == 1) numcolors++;
-
- for (i = 1; i < 255; i++) /* ignore use of colors 0 and 255 */
- if (startcolor != 0) break;
- else if (buffer[i] == 1) startcolor = i;
-
- fprintf(outfile,"LMH");
- fprintf(outfile,"%c%c",numcolors,startcolor);
- for (i = 0; i < 256; i++)
- {
- fprintf(outfile,"%c%c%c",palette[(i*3)+0],
- palette[(i*3)+1],
- palette[(i*3)+2]);
- }
-
- Dump_Fonts();
- fclose(outfile);
-
- /*
- outfile = fopen(asmfile,"wt");
- fprintf(outfile,"fontpos ");
- i1 = 5;
- for (i = 0; i < 256; i++)
- {
- // (X value * Y values) + 3 byte ASCII char,
- // X,Y header for each char
- fprintf(outfile,"dw %5u ; ASCII num %3d, char %c\n ",
- i1,i,(i >= 32 ? i: ' '));
- i1 += (xysizes[i * 2] * xysizes[(i * 2) + 1]) + 3;
- }
- */
-
- fclose(outfile);
-
- if (showflag == 0)
- {
- _asm
- {
- xor ax,ax
- int 16h
- mov ax,0003h
- int 10h
- }
- }
- free((unsigned char *) picture);
- }
- else printf("Error reading palette\n");
- }
- else printf("Error seeking to palette\n");
- }
- else printf("Not a 256 color PCX file\n");
- }
- else printf("Error reading %s\n",argv[4]);
- fclose(infile);
- }
- else printf("Error opening %s\n",argv[4]);
- }
- }
-